package etc

import (
	"os"
	"sync"

	"gin-skeleton/core/logger"
	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"
)

var (
	// Configure 配置文件全局变量
	Configure *Config
	mu        sync.RWMutex

	// 配置文件搜索路径
	configSearchPaths []string
)

func initConfigSearchPaths(){
	configSearchPaths = []string{
		"./config",
		"/etc/" + os.Args[0],
		"$HOME/." + os.Args[0],
		".",
	}
	appConfigPath := os.Getenv("APP_CONFIG_PATH")
	if appConfigPath != "" {
		configSearchPaths = append([]string{
			appConfigPath,
		}, configSearchPaths[:]...)
	}
}

// InitConfig 初始化解析配置信息
func InitConfig() {
	// 初始化配置文件搜索路径
	initConfigSearchPaths()

	Configure = &Config{}

	viper.SetConfigName("config")
	viper.SetConfigType("yaml")
	for _, configPath := range configSearchPaths {
		viper.AddConfigPath(configPath)
	}

	// 绑定环境变量
	viper.AutomaticEnv()

	if err := viper.ReadInConfig(); err != nil {
		if _, ok := err.(viper.ConfigFileNotFoundError); ok {
			// Config file not found; ignore error if desired
			logger.Get().Error("Config file not found")
		} else {
			// Config file was found but another error was produced
			logger.Get().Error("Config file not found,err:", err)
		}
		return
	}
	err := viper.Unmarshal(Configure)
	if err != nil {
		return
	}
	viper.OnConfigChange(func(e fsnotify.Event) {
		logger.Get().Debug("Config file changed:", e.Name)
	})
	viper.WatchConfig()
	// 初始化Gorm数据库配置
	initGormConfig()
}

// Load 协程安全的获取配置数据
func Load() *Config {
	mu.RLock()
	defer func() { mu.RUnlock() }()
	return Configure
}

// Store 协程内可安全设置配置数据,用于动态修改配置数据
func Store(config *Config) {
	mu.Lock()
	defer func() { mu.Unlock() }()
	Configure = config
}

// Viper 配置类
func Viper() *viper.Viper{
	return viper.GetViper()
}
